package com.utbm.lo54.dao.neo4j;

import java.util.Set;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;

import com.utbm.lo54.dao.LocationDAOInterface;
import com.utbm.lo54.entity.Location;

public class Neo4jLocationDAO implements LocationDAOInterface {

	@Override
	public Location create(Location loc) {
		Node firstNode;

		GraphDatabaseService graphDb = Neo4jUtility.getGraphDatabase();

		Transaction tx = graphDb.beginTx();
		try
		{
			Node foundNode=Neo4jUtility.getNodeIndex().get("CITY", loc.getCity()).getSingle();
			if (foundNode!=null) return nodeToLocation(foundNode);
			firstNode = Neo4jUtility.createAndIndex("CITY",  loc.getCity());
			locationToNode(loc,firstNode);
			loc.setId(firstNode.getId());
			firstNode.createRelationshipTo(Neo4jUtility.getRootNode(), Neo4jUtility.RelTypes.PROPOSED);
			tx.success();
		}
		finally
		{
			tx.finish();
		}
		return loc;
	}

	private Node locationToNode(Location loc, Node n) {
		n.setProperty(LocationProperties.CITY.name(), loc.getCity());
		n.setProperty(LocationProperties.TYPE.name(), "LOCATION");
		return n;
		
	}

	private Location nodeToLocation(Node n) {
		Location loc = new Location();
		loc.setCity((n.getProperty(LocationProperties.CITY.name()).toString()));
		loc.setId(n.getId());
		return loc;
	}

	@Override
	public void delete(Location loc) {
		Node locationNode;
		GraphDatabaseService graphDb = Neo4jUtility.getGraphDatabase();
		Transaction tx = graphDb.beginTx();
		try
		{
			locationNode = graphDb.getNodeById(loc.getId());
			Neo4jUtility.getNodeIndex().remove(locationNode);
			Iterable<Relationship> rels = locationNode.getRelationships(); // Get all the relationships and iterate to delete them one by one
			for(Relationship rel : rels){
				rel.delete();
			}
			locationNode.delete();			
			tx.success();
		}
		finally
		{
			tx.finish();
		}
	}

	@Override
	public Location findByCity(String city) {
		Node foundNode=Neo4jUtility.getNodeIndex().get("CITY", city).getSingle();
		if (foundNode!=null) return nodeToLocation(foundNode);
		return null;
	}

	@Override
	public Location findById(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void update(Location lo) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Set<Location> getAllLocation() {
		// TODO Auto-generated method stub
		return null;
	}

}
